using System;
namespace ch.ethz.ssh2.crypto.digest
{
	
	/// <summary> MAC.
	/// 
	/// </summary>
	/// <author>  Christian Plattner
	/// </author>
	/// <version>  2.50, 03/15/10
	/// </version>
	public sealed class MAC
	{
		public static System.String[] MacList
		{
			get
			{
				/* Higher Priority First */
				
				return new System.String[]{"hmac-sha1-96", "hmac-sha1", "hmac-md5-96", "hmac-md5"};
			}
			
		}
		internal Digest mac;
		internal int _size;
		
		public static void  checkMacList(System.String[] macs)
		{
			for (int i = 0; i < macs.Length; i++)
				getKeyLen(macs[i]);
		}
		
		public static int getKeyLen(System.String type)
		{
			if (type.Equals("hmac-sha1"))
				return 20;
			if (type.Equals("hmac-sha1-96"))
				return 20;
			if (type.Equals("hmac-md5"))
				return 16;
			if (type.Equals("hmac-md5-96"))
				return 16;
			throw new System.ArgumentException("Unkown algorithm " + type);
		}
		
		public MAC(System.String type, byte[] key)
		{
			if (type.Equals("hmac-sha1"))
			{
				mac = new HMAC(new SHA1(), key, 20);
			}
			else if (type.Equals("hmac-sha1-96"))
			{
				mac = new HMAC(new SHA1(), key, 12);
			}
			else if (type.Equals("hmac-md5"))
			{
				mac = new HMAC(new MD5(), key, 16);
			}
			else if (type.Equals("hmac-md5-96"))
			{
				mac = new HMAC(new MD5(), key, 12);
			}
			else
				throw new System.ArgumentException("Unkown algorithm " + type);
			
			_size = mac.DigestLength;
		}
		
		public void  initMac(int seq)
		{
			mac.reset();
			mac.update((byte) (seq >> 24));
			mac.update((byte) (seq >> 16));
			mac.update((byte) (seq >> 8));
			mac.update((byte) (seq));
		}
		
		public void  update(byte[] packetdata, int off, int len)
		{
			mac.update(packetdata, off, len);
		}
		
		public void  getMac(byte[] output, int off)
		{
			mac.digest(output, off);
		}
		
		public int size()
		{
			return _size;
		}
	}
}